import { ref, watch, onUnmounted } from 'vue'

export interface UseFetchOptions {
  immediate?: boolean
  refetch?: boolean
}

export interface UseFetchResult<T> {
  data: any
  loading: any
  error: any
  execute: () => Promise<void>
  refresh: () => Promise<void>
}

export function useFetch<T = any>(
  url: string | (() => string),
  options: UseFetchOptions = {},
): UseFetchResult<T> {
  const { immediate = true, refetch = false } = options

  const data = ref<T | null>(null)
  const loading = ref(false)
  const error = ref<Error | null>(null)

  let abortController: AbortController | null = null

  const getUrl = () => {
    return typeof url === 'function' ? url() : url
  }

  const execute = async () => {
    // 取消之前的请求
    if (abortController) {
      abortController.abort()
    }

    abortController = new AbortController()
    loading.value = true
    error.value = null

    try {
      const response = await fetch(getUrl(), {
        signal: abortController.signal,
      })

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`)
      }

      const result = await response.json()
      data.value = result
    } catch (err) {
      // 忽略用户主动取消的请求
      if (err instanceof Error && err.name === 'AbortError') {
        return
      }
      error.value = err instanceof Error ? err : new Error('Unknown error occurred')
      data.value = null
    } finally {
      loading.value = false
      abortController = null
    }
  }

  const refresh = async () => {
    await execute()
  }

  // 如果 immediate 为 true，立即执行
  if (immediate) {
    execute()
  }

  // 如果 refetch 为 true，监听 URL 变化
  if (refetch && typeof url === 'function') {
    watch(
      () => getUrl(),
      () => {
        execute()
      },
    )
  }

  // 组件卸载时取消请求
  onUnmounted(() => {
    if (abortController) {
      abortController.abort()
    }
  })

  return {
    data,
    loading,
    error,
    execute,
    refresh,
  }
}
